home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / evalx.com / CLASS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-15  |  6.1 KB  |  319 lines

  1. /*    +-----------------------------------+
  2.  *    |                                   |
  3.  *    |              CLASS.C              |
  4.  *    |                                   |
  5.  *    +-----------------------------------+
  6.  *
  7.  *    James. P. Hawkins - WA2WHV
  8.  *    P.O. Box 9146,
  9.  *    Trenton, NJ 08650
  10.  *
  11.  *      ALGEBRAIC EXPRESSION FIELD and OPERATOR CLASSIFIER
  12.  *                 and SYNTAX CHECKER
  13.  *        (LEXICAL analyzer of sorts)
  14.  *
  15.  *
  16.  * calling format:
  17.  *
  18.  *    field class (or error) = class(&sptr, field);
  19.  *
  20.  *    where the ADDRESS of the Pointer sptr MUST be passed
  21.  *        the input string pointer will be MODIFIED and
  22.  *        LEFT at a point after the field just parsed
  23.  *
  24.  *        field = pointer to txtbuf where a null terminated copy
  25.  *            of the field just parsed will be left
  26.  *
  27.  *        error code = negative of class
  28.  *            (i.e. a certain type field was attempted
  29.  *             but something illegal happened
  30.  */
  31. #include    "evalx.h"
  32. /*
  33.  * the legdlm(X)  check for legal delimeters or null (end of string)
  34.  */
  35. #define cpychr()    {*fptr++ = **sptr ; *sptr += 1; }
  36. #define legdlm(X) (any(X," ^*+/-)")  || (X =='\0'))
  37.  
  38. /* Skip white space macro */
  39. #define    skipspace()    {while(**sptr == ' ' || **sptr == '\t') *sptr +=1;}
  40.  
  41. /* -------------------------------------------------------------------- */
  42. class(sptr, field)
  43. char    **sptr;        /* input string pointer */
  44. char    *field;        /* pointer to output field */
  45. {
  46.     char    *fptr;    /* output field pointer */
  47.     int    pcnt;    /* parenthesis best counter */
  48.  
  49.  
  50.     pcnt = 0;    /* init paren nest counter */
  51.     fptr = field;    /* init output field pointer */
  52.     skipspace();        /* skip leading blanks and tabs */
  53.  
  54.     if(alpha(**sptr))    /* if 1st char is alpha */
  55.     {
  56.         cpychr();    /* copy first alpha */
  57.         if(alpha(**sptr))    /* if second alpha it must be func */
  58.         {
  59.             /*
  60.              * Copy until first non-alphanumeric
  61.              * this must be a FUNCTION FIELD.
  62.              * The first non-alpha numeric must be a '('
  63.              */
  64.             while(alpha(**sptr) || num(**sptr))
  65.             {
  66.                 cpychr();
  67.             }
  68.  
  69.             if(**sptr == '(') /* func name followed by '(' */
  70.             {
  71.                 pcnt = 1; /* count first nest deep */
  72.                 cpychr(); /* copy initial '(' */
  73.                 /*
  74.                  * Scan stuff inside of parens.
  75.                  * parens must be balanced to terminate
  76.                  * function field.
  77.                  */
  78.                 while(pcnt > 0 && **sptr != 0)
  79.                 {
  80.                     switch(**sptr)
  81.                     {
  82.                     case '(':
  83.                         pcnt += 1;
  84.                         break;
  85.                     case ')':
  86.                         pcnt -= 1;
  87.                         break;
  88.                     default:
  89.                         break;
  90.                     }
  91.                     cpychr();
  92.                 }
  93.  
  94.                 if(**sptr == 0 && pcnt != 0)
  95.                 {
  96.                     *fptr='\0';
  97.                     /*
  98.                      * line terminates before
  99.                      * function defined.
  100.                      */
  101.                     return(-FNCLASS);
  102.                 }
  103.  
  104.                 if(legdlm(**sptr))
  105.                 {
  106.                     *fptr = '\0'; /* null term */
  107.                     /*
  108.                      * Return function class code
  109.                      */
  110.                     return(FNCLASS);
  111.                 }
  112.                 else /* illegal delim */
  113.                 {
  114.                     return(-FNCLASS);
  115.                 }
  116.             }
  117.             else
  118.             {
  119.                 return(-FNCLASS); /* function def without
  120.                               '('  */
  121.             }
  122.         }
  123.         else    /* VARIABLE OR VARIABLE ARRAY FIELD */
  124.         {
  125.             if(num(**sptr))
  126.             {
  127.                 cpychr(); /* cpy numeric part of var name */
  128.             }
  129.  
  130.             if(**sptr == '(') /* array paren? */
  131.             {
  132.                 pcnt = 1;    /* init paren count */
  133.                 cpychr();    /* copy 1st paren */
  134.                 /*
  135.                  * scan stuff inside of parens.
  136.                  * parens must be balanced to terminate
  137.                  * function field.
  138.                  */
  139.                 while(pcnt > 0 && **sptr != 0)
  140.                 {
  141.                     switch(**sptr)
  142.                     {
  143.                     case '(':
  144.                         pcnt += 1;
  145.                         break;
  146.                     case ')':
  147.                         pcnt -= 1;
  148.                         break;
  149.                     default:
  150.                         break;
  151.                     }
  152.                     cpychr();
  153.                 }
  154.  
  155.                 if(**sptr == 0 && pcnt != 0)
  156.                 {
  157.                     *fptr='\0';
  158.                     /*
  159.                      * line terminates before array
  160.                      * defined
  161.                      */
  162.                     return(-VACLASS);
  163.                 }
  164.                 if(legdlm(**sptr))
  165.                 {
  166.                     *fptr = '\0'; /* null term */
  167.                     return(VACLASS);
  168.                 }
  169.                 else
  170.                 {
  171.                     *fptr = '\0';
  172.                     /* ill delim */
  173.                     return(-VACLASS);
  174.                 }
  175.             }
  176.             else /* VARIABLE NAME FIELD */
  177.             {
  178.                 if(legdlm(**sptr)) /* legal delimiter */
  179.                 {
  180.                     *fptr = '\0'; /* null term */
  181.                     return(VRCLASS);
  182.                 }
  183.                 else
  184.                 {
  185.                     return(-VRCLASS); /* ill delim */
  186.                 }
  187.             }
  188.         }
  189.     }
  190.     else /* EITHER NUMERIC OR OPERATOR FIELD */
  191.     {
  192.         if(num(**sptr) || **sptr == '.')
  193.         {
  194.             cpychr(); /* copy 1st dig of num */
  195.  
  196.             while(num(**sptr)) /* copy all consec dig */
  197.             {
  198.                 cpychr();
  199.             }
  200.  
  201.             if(**sptr == '.') /* embedded '.' is allowed */
  202.             {
  203.                 cpychr();    /* copy '.' */
  204.                 while(num(**sptr)) /* get digits following
  205.                               decimal point */
  206.                 {
  207.                     cpychr();
  208.                 }
  209.             }
  210.             if(**sptr == 'e' || **sptr == 'E')
  211.             {
  212.                 cpychr();
  213.                 /*
  214.                  * HANDLE EXPONENTIAL NOTATION TYPE
  215.                  */
  216.                 if(**sptr == '+' || **sptr == '-')
  217.                 {
  218.                     cpychr();
  219.                     if(num(**sptr))
  220.                     {
  221.                         /* copy exponent */
  222.                         while(num(**sptr))
  223.                         {
  224.                             cpychr();
  225.                         }
  226.                     }
  227.                     else
  228.                     {
  229.                         return(-NMCLASS);
  230.                     }
  231.                 }
  232.                 else
  233.                 {
  234.                     return(-NMCLASS);
  235.                 }
  236.             }
  237.             if(legdlm(**sptr)) /* check for legal delim */
  238.             {
  239.                 *fptr = '\0'; /* null term */
  240.                 return(NMCLASS); /* numeric */
  241.             }
  242.             else
  243.             {
  244.                 return(-NMCLASS); /* ill delim */
  245.             }
  246.         }
  247.         else /* OPERATOR FIELD */
  248.         {
  249.             if(any(**sptr, "^*/+-()"))
  250.             {
  251.                 cpychr(); /* copy the operator */
  252.                 *fptr = '\0'; /* term with null */
  253.                 return(OPCLASS); /* operator */
  254.             }
  255.             else
  256.             {
  257.                 return(-OPCLASS); /* illegal delim */
  258.             }
  259.         }
  260.     }
  261. }
  262.  
  263. /* ------------------------------------------------------------------- */
  264. /*
  265.  *
  266.  * //////// TRUE IF ANY CHARS IN STRING as MATCH c ////////
  267.  */
  268. any(c, as)
  269. int c;
  270. char *as;
  271. {
  272.     register char *s;
  273.  
  274.     s = as;
  275.     while(*s)
  276.     {
  277.         if(*s++ == c)
  278.         {
  279.             return(1);
  280.         }
  281.     }
  282.     return(0);
  283. }
  284.  
  285.  
  286. /* ------------------------------------------------------------------- */
  287. /*
  288.  * //// TRUE IF NUMERIC ////
  289.  */
  290. num(c)
  291. char    c;
  292. {
  293.     if(c >= '0' && c <= '9')
  294.     {
  295.         return(1);
  296.     }
  297.     else
  298.     {
  299.         return(0);
  300.     }
  301. }
  302.  
  303. /* ------------------------------------------------------------------- */
  304. /*
  305.  * //// TRUE IF ALPHA lower case ////
  306.  */
  307. alpha(c)
  308. char    c;
  309. {
  310.     if(c >= 'a' && c <= 'z')
  311.     {
  312.         return(1);
  313.     }
  314.     else
  315.     {
  316.         return(0);
  317.     }
  318. }
  319.